using System;
using System.Collections.Generic;
using FilteredStatistics.Data;
using ZoneFiveSoftware.Common.Data.Fitness;
using ZoneFiveSoftware.Common.Data;

namespace FilteredStatistics.Controller
{
    class PostProcessFilterController
    {
        public static FilterResults ApplyPostProcessFilters(FilterList filters, FilterResults filterResult, IActivity activity)
        {
            List<IPostProcessFilter> postProcessFilters = RegroupPostProcessFiltersInList(filters);
            List<ActivityRangeInfoCache> ranges = new List<ActivityRangeInfoCache>();
            FilterResults result = new FilterResults();

            // Add a 0 second merge PP to prevent consecutive sections
            postProcessFilters.Sort();

            // Copy ranges in a temp list
            foreach (ValueRange<DateTime> currentRange in filterResult)
            {
                ranges.Add(new ActivityRangeInfoCache(currentRange, activity));
            }

            IPostProcessFilter mergeConsecutive = new MergeNearTimesPostProcessFilter(new TimeSpan(0, 0, 0));
            ranges = mergeConsecutive.FilterResults(ranges, activity);

            // Apply filters in list
            foreach (IPostProcessFilter PPFilter in postProcessFilters)
            {
                ranges = PPFilter.FilterResults(ranges, activity);
            }

            // Restore in a FilterResults list
            foreach (ActivityRangeInfoCache currentRange in ranges)
            {
                // Make sure not to add results that have no length
                if (!currentRange.RangeWithPauses.Lower.Equals(currentRange.RangeWithPauses.Upper))
                {
                    result.Add(currentRange.RangeWithPauses);
                }
            }

            return result;
        }

        private static List<IPostProcessFilter> RegroupPostProcessFiltersInList(FilterList filters)
        {
            List<IPostProcessFilter> result = new List<IPostProcessFilter>();

            foreach (Filter currentFilter in filters)
            {
                if (currentFilter.CriteriaFacade is PostProcessFilterCriteria)
                {
                    PostProcessFilterCriteria criteria = currentFilter.CriteriaFacade as PostProcessFilterCriteria;

                    foreach (PostProcessNamedZone namedZone in currentFilter.Zones)
                    {
                        result.Add(namedZone.PostProcessFilter);
                    }
                }
                else if (currentFilter.CriteriaFacade is TemplateFilterCriteria)
                {
                    foreach(TemplateNamedZone namedZone in currentFilter.Zones)
                    {
                        List<IPostProcessFilter> temp;

                        temp = RegroupPostProcessFiltersInList(namedZone.Template.Filters);
                        result.AddRange(temp);
                    }
                }
            }

            return result;
        }
    }
}
